using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Globalization;
using Musicman.Client.Utilities;
using System.Security.Cryptography;
using System.Diagnostics;

namespace Musicman.Client
{
    public partial class MusicmanClient2 : Form
    {
        internal LoginForm loginForm;
        private CopyForm copyForm;
        private FileManagerService.FileManagerService fmService;
        internal AuthenticationService.AuthenticationService aService;
        internal AuthenticationService.AuthHeader aHeader;
        private FeedbackService.FeedbackService fdbService;
        private AutomaticDownloaderSettings automaticDnloaderSettings;
        private AutomaticDownloader automaticDownloader;
        private CultureInfo MyCi = new CultureInfo("en-US");
        
        
        public MusicmanClient2()
        {
            InitializeComponent();
        }

        public void InitializeMe()
        {
            InitializeGridViews();
            this.fmService = new Musicman.Client.FileManagerService.FileManagerService();
            this.fmService.SearchFilesCompleted += new Musicman.Client.FileManagerService.SearchFilesCompletedEventHandler(fmService_SearchFilesCompleted);
            this.fmService.TopDownloadsCompleted += new Musicman.Client.FileManagerService.TopDownloadsCompletedEventHandler(fmService_TopDownloadsCompleted);
            this.fmService.TopRatedCompleted += new Musicman.Client.FileManagerService.TopRatedCompletedEventHandler(fmService_TopRatedCompleted);
            this.fmService.SearchFilesRandomCompleted += new Musicman.Client.FileManagerService.SearchFilesRandomCompletedEventHandler(fmService_SearchFilesRandomCompleted);
            this.fmService.SearchFilesLatestCompleted += new Musicman.Client.FileManagerService.SearchFilesLatestCompletedEventHandler(fmService_SearchFilesLatestCompleted);
            this.fmService.GetFolderFilesCompleted += new Musicman.Client.FileManagerService.GetFolderFilesCompletedEventHandler(fmService_GetFolderFilesCompleted);
            this.fdbService = new Musicman.Client.FeedbackService.FeedbackService();
            this.fdbService.LoadUserFeedbackDatesCompleted += new Musicman.Client.FeedbackService.LoadUserFeedbackDatesCompletedEventHandler(fdbService_LoadUserFeedbackDatesCompleted);
            this.fdbService.LoadFeedbackPerDayCompleted += new Musicman.Client.FeedbackService.LoadFeedbackPerDayCompletedEventHandler(fdbService_LoadFeedbackPerDayCompleted);
            this.lblTItle.Text = String.Format("Musicman Levi9 Logged in as: {0} {1} ({2} / {3}) ",
                    loginForm.User.Firstname,
                    loginForm.User.Lastname,
                    loginForm.UserLogins,
                    loginForm.TotalLogins);
            Musicman.Client.FileManagerService.Searchjob[] jobs = this.fmService.GetSearchJobs();
            BindingSource bs = new BindingSource();
            bs.DataSource = jobs;
            this.comboJobType.DataSource = bs;
            this.comboJobType.ValueMember = "Searchjobid";
            this.comboJobType.DisplayMember = "Name";
            this.automaticDnloaderSettings = DeserializeDownloaderSettings();
            this.automaticDownloader = new AutomaticDownloader(this.automaticDnloaderSettings,
                                                               this.fmService,
                                                               (long)this.loginForm.User.Personid);
            this.copyForm = new CopyForm(this.fmService, automaticDownloader, (long)loginForm.User.Personid);
            this.automaticDownloader.ActionMessage += new AlertDownloaderMessage(automaticDownloader_ActionMessage);
            BindDownloaderProperties(automaticDownloader);
            BindUserProperties(loginForm.User);
        }

        void automaticDownloader_ActionMessage(string message)
        {
            this.notifyIcon1.ShowBalloonTip(1000, "", message, ToolTipIcon.None);
        }

        private AutomaticDownloaderSettings DeserializeDownloaderSettings()
        {
            string settingsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal).ToString() + "\\settings.srl";
            AutomaticDownloaderSettings res;
            if (File.Exists(settingsPath))
            {
                FileStream fs = File.Open(settingsPath, FileMode.Open, FileAccess.Read);
                BinaryFormatter bf = new BinaryFormatter();
                res = (AutomaticDownloaderSettings)bf.Deserialize(fs);
                fs.Close();
            }
            else
            {
                res = new AutomaticDownloaderSettings();
            }
            return res;
        }

        private void BindDownloaderProperties(AutomaticDownloader automaticDownloader)
        {
            this.cbUseAutomaticDownloader.DataBindings.Add(new Binding("Checked", automaticDownloader.Settings, "UseDownloader"));
            this.upDownRetryTimes.DataBindings.Add(new Binding("Value", automaticDownloader.Settings, "RetryTimes"));
            this.comboFailureAction.DataSource = automaticDownloader.Settings.FailureActions;
            this.comboFailureAction.DataBindings.Add(new Binding("SelectedItem", automaticDownloader.Settings, "FailureAction"));
            this.upDownRetryMin.DataBindings.Add(new Binding("Value", automaticDownloader.Settings, "RetryMin"));
            this.cbUseDefaultFolder.DataBindings.Add(new Binding("Checked", automaticDownloader.Settings, "UseDefaultFolder"));
            this.txtDefaultFolder.Enabled = this.cbUseDefaultFolder.Checked;
            this.txtDefaultFolder.DataBindings.Add(new Binding("Text", automaticDownloader.Settings, "DefaultFolder"));
            this.toolTip1.SetToolTip(this.txtDefaultFolder, this.txtDefaultFolder.Text);
        }

        private void BindUserProperties(Musicman.Client.AuthenticationService.User user)
        {
            this.firstNameTxt.DataBindings.Add(new Binding("Text", user, "Firstname"));
            this.lastNameTxt.DataBindings.Add(new Binding("Text", user, "Lastname"));
            this.emailAddressTxt.DataBindings.Add(new Binding("Text", user, "Emailaddress"));
            this.emailRqCb.DataBindings.Add(new Binding("Checked", user, "MailRequest"));
        }

        void fmService_SearchFilesCompleted(object sender, Musicman.Client.FileManagerService.SearchFilesCompletedEventArgs e)
        {
            FillSearchGridView(e.Cancelled, e.Result, (long)e.UserState);
        }

        void fmService_TopDownloadsCompleted(object sender, Musicman.Client.FileManagerService.TopDownloadsCompletedEventArgs e)
        {
            FillSearchGridView(e.Cancelled, e.Result, (long)e.UserState);
        }

        void fmService_TopRatedCompleted(object sender, Musicman.Client.FileManagerService.TopRatedCompletedEventArgs e)
        {
            FillSearchGridView(e.Cancelled, e.Result, (long)e.UserState);
        }

        void fmService_SearchFilesRandomCompleted(object sender, Musicman.Client.FileManagerService.SearchFilesRandomCompletedEventArgs e)
        {
            FillSearchGridView(e.Cancelled, e.Result, (long)e.UserState);
        }

        void fmService_SearchFilesLatestCompleted(object sender, Musicman.Client.FileManagerService.SearchFilesLatestCompletedEventArgs e)
        {
            FillSearchGridView(e.Cancelled, e.Result, (long)e.UserState);
        }

        void fmService_GetFolderFilesCompleted(object sender, Musicman.Client.FileManagerService.GetFolderFilesCompletedEventArgs e)
        {
            FillSearchGridView(e.Cancelled, e.Result, (long)e.UserState);
        }

        private void FillSearchGridView(bool canceled, Musicman.Client.FileManagerService.SearchResult[] res, long startTicks)
        {
            if (!canceled)
            {
                ((BindingSource)this.dgvSearchResults.DataSource).DataSource = res;
                lblSearchInfo.Text = String.Format("{0} files found in {1} seconds", res.Length, TicksToSeconds(DateTime.Now.Ticks - startTicks));
            }
            this.lblLoading.Visible = false;
            this.dgvSearchResults.Visible = true;
        }

        #region initialization
        private void InitializeGridViews()
        {
            List<Musicman.Client.FileManagerService.SearchResult> files = new List<Musicman.Client.FileManagerService.SearchResult>();
            BindingSource bs = new BindingSource();
            bs.DataSource = files;
            dgvSearchResults.DataSource = bs;

            BindingSource bs1 = new BindingSource();
            bs1.DataSource = files;
            dgvPendingDownloads.DataSource = bs1;

            List<Musicman.Client.FileManagerService.Searchjob> jobs = new List<Musicman.Client.FileManagerService.Searchjob>();
            BindingSource bs2 = new BindingSource();
            bs2.DataSource = jobs;
            dgvSearchJobInfo.DataSource = bs2;

            List<Musicman.Client.FileManagerService.UserActivity> activity = new List<Musicman.Client.FileManagerService.UserActivity>();
            BindingSource bs3 = new BindingSource();
            bs3.DataSource = activity;
            dgvTopLoggers.DataSource = bs3;

            BindingSource bs4 = new BindingSource();
            bs4.DataSource = activity;
            dgvTopDownloaders.DataSource = bs4;

            List<DateTime> dates = new List<DateTime>();
            BindingSource bs5 = new BindingSource();
            bs5.DataSource = dates;
            dgvFeedBackDates.DataSource = bs5;

            List<Musicman.Client.FeedbackService.Userfeedback> feedbacks = new List<Musicman.Client.FeedbackService.Userfeedback>();
            BindingSource bs6 = new BindingSource();
            bs6.DataSource = feedbacks;
            dgvFeedbacks.DataSource = bs6;

            SetSearchFileApereance(dgvSearchResults);
            SetSearchFileApereance(dgvPendingDownloads);
            SetSearchJobsInfoAppereance();
            SetTopLoggersApereance();
            SetTopDownloadersApereance();
            SetFeedbackDatesApereance();
            SetFeedbacksApereance();

        }

        private void SetSearchFileApereance(DataGridView dataGridView)
        {
            dataGridView.Columns["FileID"].Visible = false;
            dataGridView.Columns["Fullpath"].Visible = false;
            dataGridView.Columns["Length"].Visible = false;
            dataGridView.Columns["Name"].Visible = true;
            dataGridView.Columns["Location"].Visible = true;
            dataGridView.Columns["TotalLengthMB"].Visible = true;
            dataGridView.Columns["Name"].Width = 340;
            dataGridView.Columns["Location"].Width = 70;
            dataGridView.Columns["TotalLengthMB"].Width = 70;
            dataGridView.Columns["TotalLengthMB"].HeaderText = "Size";
            dataGridView.Columns["TotalLengthMB"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            
        }

        private void SetSearchJobsInfoAppereance()
        {
            dgvSearchJobInfo.Columns["Searchjobid"].Visible = false;
            dgvSearchJobInfo.Columns["Name"].Visible = true;
            dgvSearchJobInfo.Columns["Allcriteria"].Visible = true;
            dgvSearchJobInfo.Columns["Allcriteria"].Width = 300;
            dgvSearchJobInfo.Columns["Type"].Visible = false;
            dgvSearchJobInfo.Columns["Starttime"].Visible = true;
            dgvSearchJobInfo.Columns["Endtime"].Visible = true;
            dgvSearchJobInfo.Columns["Totalfiles"].Visible = true;
            dgvSearchJobInfo.Columns["Totalfiles"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            dgvSearchJobInfo.Columns["Totallength"].Visible = false;
            dgvSearchJobInfo.Columns["TotalLengthGB"].Visible = true;
            dgvSearchJobInfo.Columns["TotalLengthGB"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
        }

        private void SetTopLoggersApereance()
        {
            dgvTopLoggers.Columns["PersonID"].Visible = false;
            dgvTopLoggers.Columns["NumLogsWeb"].Visible = true;
            dgvTopLoggers.Columns["NumLogsWeb"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            dgvTopLoggers.Columns["NumLogsClient"].Visible = true;
            dgvTopLoggers.Columns["NumLogsClient"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            dgvTopLoggers.Columns["Totalfiles"].Visible = false;
            dgvTopLoggers.Columns["TotalTraffic"].Visible = false;
            dgvTopLoggers.Columns["FirstName"].Visible = true;
            dgvTopLoggers.Columns["LastName"].Visible = true;
            dgvTopLoggers.Columns["FirstName"].DisplayIndex = 0;
            dgvTopLoggers.Columns["LastName"].Visible = true;
            dgvTopLoggers.Columns["LastName"].DisplayIndex = 1;
            dgvTopLoggers.Columns["TotalLengthMB"].Visible = false;
        }

        private void SetTopDownloadersApereance()
        {
            dgvTopDownloaders.Columns["PersonID"].Visible = false;
            dgvTopDownloaders.Columns["NumLogsWeb"].Visible = false;
            dgvTopDownloaders.Columns["NumLogsClient"].Visible = false;
            dgvTopDownloaders.Columns["Totalfiles"].Visible = true;
            dgvTopDownloaders.Columns["Totalfiles"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; Visible = true;
            dgvTopDownloaders.Columns["TotalTraffic"].Visible = false;
            dgvTopDownloaders.Columns["TotalLengthMB"].Visible = true;
            dgvTopDownloaders.Columns["TotalLengthMB"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; Visible = true;
            dgvTopDownloaders.Columns["TotalLengthMB"].DisplayIndex = 3;
            dgvTopDownloaders.Columns["FirstName"].Visible = true;
            dgvTopDownloaders.Columns["FirstName"].DisplayIndex = 0;
            dgvTopDownloaders.Columns["LastName"].Visible = true;
            dgvTopDownloaders.Columns["LastName"].DisplayIndex = 1;
        }

        private void SetFeedbackDatesApereance()
        {
            for (int i = 0; i < dgvFeedBackDates.Columns.Count; i++)
            {
                DataGridViewColumn column = dgvFeedBackDates.Columns[i];
                column.Visible = false;
            }
            dgvFeedBackDates.Columns["Date"].Visible = true;
        }

        private void SetFeedbacksApereance()
        {
            for (int i = 0; i < dgvFeedbacks.Columns.Count; i++)
            {
                DataGridViewColumn column = dgvFeedbacks.Columns[i];
                column.Visible = false;
            }
            dgvFeedbacks.Columns["From"].Visible = true;
            dgvFeedbacks.Columns["Date"].Visible = true;
        }
        #endregion

        #region Form Dragging API Support
        //The SendMessage function sends a message to a window or windows.

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]

        static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

        //ReleaseCapture releases a mouse capture

        [DllImportAttribute("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]

        public static extern bool ReleaseCapture();

        #endregion

        #region WindowEvents
        private void MusicmanClient2_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                SendMessage(this.Handle, 0xa1, 0x2, 0);
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void button7_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        private void MusicmanClient2_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Visible = false;
            }
        }

        private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
        }

        private void MusicmanClient2_FormClosing(object sender, FormClosingEventArgs e)
        {
            FileStream fs = null;
            string userPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal).ToString() + "\\user.srl";
            try
            {
                if (this.loginForm.RememberMe)
                {
                    fs = File.Open(userPath, FileMode.Create, FileAccess.Write);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, this.loginForm.User);
                    fs.Flush();
                    fs.Close();
                }
                else if (File.Exists(userPath))
                {
                    File.Delete(userPath);
                }
            }
            catch (Exception ex)
            {
                fmService.LogClientException((long)loginForm.User.Personid, 
                    "Error serializing user", 
                    ex.Message, 
                    (ex.InnerException == null) ? "" : ex.InnerException.Message);
                if (fs != null) fs.Close();
                File.Delete(userPath);
            }
            this.automaticDownloader.StopDownloader();
        }

        #endregion

        private void Toggle_Pannels(object sender, EventArgs e)
        {
            ToolStripButton toolButton = (ToolStripButton)sender;
            switch (toolButton.Text.ToLower())
            {
                case "search": this.maintabControl.SelectedTab = this.tabSearch; break;
                case "pending downloads":
                    this.maintabControl.SelectedTab = this.tabPendingDownloads;
                    LoadPendingDownloads();
                    break;
                case "statistics": 
                    this.maintabControl.SelectedTab = this.tabStatistics;
                    LoadSearchJobsInfo();
                    LoadTopLoggers();
                    LoadTopDownloaders();
                    break;
                case "settings": 
                    this.maintabControl.SelectedTab = this.tabSettings;
                    LoadUseerActivity();
                    break;
                case "feedback": 
                    this.maintabControl.SelectedTab = this.tabFeedback;
                    LoadUserFeedbackDates();
                    break;
                case "help": this.maintabControl.SelectedTab = this.tabHelp; break;
            }
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            SearchFiles();
        }

        private void txtKeywords_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                SearchFiles();
            }
        }

        private void SearchFiles()
        {
            long startTicks = DateTime.Now.Ticks;
            int count = 0;
            Int32.TryParse(txtCount.Text, out count);
            this.dgvSearchResults.Visible = false;
            this.lblLoading.Visible = true;
            fmService.SearchFilesAsync(count, (long)this.comboJobType.SelectedValue, this.txtKeywords.Text, startTicks);
        }

        private void btnTopDownloads_Click(object sender, EventArgs e)
        {
            long startTicks = DateTime.Now.Ticks;
            int count = 0;
            if (!Int32.TryParse(txtCount.Text, out count))
            {
                count = 50;
            }
            this.dgvSearchResults.Visible = false;
            this.lblLoading.Visible = true;
            fmService.TopDownloadsAsync((long)this.comboJobType.SelectedValue, this.txtKeywords.Text, count, startTicks);
        }

        private void btnTopRated_Click(object sender, EventArgs e)
        {
            long startTicks = DateTime.Now.Ticks;
            int count = 0;
            if (!Int32.TryParse(txtCount.Text, out count))
            {
                count = 50;
            }
            this.dgvSearchResults.Visible = false;
            this.lblLoading.Visible = true;
            fmService.TopRatedAsync((long)this.comboJobType.SelectedValue, this.txtKeywords.Text, count, startTicks);
        }

        private void btnRandom_Click(object sender, EventArgs e)
        {
            long startTicks = DateTime.Now.Ticks;
            int count = 0;
            if (!Int32.TryParse(txtCount.Text, out count))
            {
                count = 50;
            }
            this.dgvSearchResults.Visible = false;
            this.lblLoading.Visible = true;
            fmService.SearchFilesRandomAsync((long)this.comboJobType.SelectedValue, this.txtKeywords.Text, count, startTicks);
        }

        private void btnLatest_Click(object sender, EventArgs e)
        {
            long startTicks = DateTime.Now.Ticks;
            int count = 0;
            if (!Int32.TryParse(txtCount.Text, out count))
            {
                count = 0;
            }
            this.dgvSearchResults.Visible = false;
            this.lblLoading.Visible = true;
            fmService.SearchFilesLatestAsync((long)this.comboJobType.SelectedValue, this.txtKeywords.Text, count, startTicks);
        }

        private void sameFolderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            long startTicks = DateTime.Now.Ticks;
            int count = 0;
            if (!Int32.TryParse(txtCount.Text, out count))
            {
                count = 0;
            }
            this.dgvSearchResults.Visible = false;
            this.lblLoading.Visible = true;
            long searchFileID = (long)this.dgvSearchResults.SelectedRows[0].Cells["FileID"].Value;
            string location = (string)this.dgvSearchResults.SelectedRows[0].Cells["Location"].Value;
            fmService.GetFolderFilesAsync(searchFileID, location, startTicks);
        }

        private void btnRefresh1_Click(object sender, EventArgs e)
        {
            LoadPendingDownloads();
        }

        private void LoadPendingDownloads()
        {
            long startTicks = DateTime.Now.Ticks;
            Musicman.Client.FileManagerService.SearchResult[] res = fmService.GetPendingDownloads((long)loginForm.User.Personid);
            ((BindingSource)this.dgvPendingDownloads.DataSource).DataSource = res;
            lblSearchInfo1.Text = String.Format("{0} files found in {1} seconds", res.Length, TicksToSeconds(DateTime.Now.Ticks - startTicks));
        }

        private void LoadUseerActivity()
        {
            Musicman.Client.FileManagerService.UserActivity activity = fmService.GetUserActivity((long)loginForm.User.Personid);
            this.lblTotalLogsWebVal.Text = activity.NumLogsWeb.ToString();
            this.lblTotalLogsClientVal.Text = activity.NumLogsClient.ToString();
            this.lblTotalLogsVal.Text = String.Format("{0}", activity.NumLogsWeb + activity.NumLogsClient);
            this.lblTotalFilesVal.Text = activity.TotalFiles.ToString();
            float mbLength = (float)activity.TotalTraffic / 1048576;
            this.lblTotalTrafficVal.Text = String.Format("{0} MB", mbLength.ToString("0.00", MyCi.NumberFormat));
        }

        private void LoadSearchJobsInfo()
        {
            Musicman.Client.FileManagerService.Searchjob[] res = fmService.GetSearchJobs();
            ((BindingSource)this.dgvSearchJobInfo.DataSource).DataSource = res;
        }

        private void LoadTopLoggers()
        {
            Musicman.Client.FileManagerService.UserActivity[] res = fmService.GetTopLoggers(5);
            ((BindingSource)this.dgvTopLoggers.DataSource).DataSource = res;
        }

        private void LoadTopDownloaders()
        {
            Musicman.Client.FileManagerService.UserActivity[] res = fmService.GetTopDownloaders(5);
            ((BindingSource)this.dgvTopDownloaders.DataSource).DataSource = res;
        }

        private void LoadUserFeedbackDates()
        {
            this.dgvFeedBackDates.Visible = false;
            this.lblLoading3.Visible = true;
            fdbService.LoadUserFeedbackDatesAsync();
        }

        void fdbService_LoadUserFeedbackDatesCompleted(object sender, Musicman.Client.FeedbackService.LoadUserFeedbackDatesCompletedEventArgs e)
        {
            if (!e.Cancelled)
            {
                DateTime[] res = e.Result;
                ((BindingSource)this.dgvFeedBackDates.DataSource).DataSource = res;
            }
            this.lblLoading3.Visible = false;
            this.dgvFeedBackDates.Visible = true;
            dgvFeedBackDates_SelectionChanged(dgvFeedBackDates, new EventArgs());
        }


        private void dgvFeedBackDates_SelectionChanged(object sender, EventArgs e)
        {
            DataGridView dgv = sender as DataGridView;
            if (dgv.SelectedRows.Count == 1 && dgv.Visible)
            {
                int index = dgv.SelectedRows[0].Index;
                DateTime day = ((DateTime[])(((BindingSource)dgv.DataSource).DataSource))[index];
                string dateParam = String.Format("{0}-{1}-{2}", day.Year, day.Month, day.Day);
                this.dgvFeedbacks.Visible = false;
                this.lblLoading2.Visible = true;
                fdbService.LoadFeedbackPerDayAsync(dateParam);
            }
        }

        void fdbService_LoadFeedbackPerDayCompleted(object sender, Musicman.Client.FeedbackService.LoadFeedbackPerDayCompletedEventArgs e)
        {

            Musicman.Client.FeedbackService.Userfeedback[] res = e.Result;
            ((BindingSource)this.dgvFeedbacks.DataSource).DataSource = res;
            this.lblLoading2.Visible = false;
            this.dgvFeedbacks.Visible = true;
        }

        private void btnDownload_Click(object sender, EventArgs e)
        {
            if (this.automaticDownloader.Settings.UseDefaultFolder && Directory.Exists(this.automaticDownloader.Settings.DefaultFolder))
            {
                DownloadSelectedFiles(this.dgvSearchResults, this.automaticDownloader.Settings.DefaultFolder);
            } 
            else if (this.copyFolderDialog.ShowDialog() == DialogResult.OK && Directory.Exists(this.copyFolderDialog.SelectedPath))
            {
                DownloadSelectedFiles(this.dgvSearchResults, this.copyFolderDialog.SelectedPath);
            }
        }

        private void btnDownload1_Click(object sender, EventArgs e)
        {
            if (this.automaticDownloader.Settings.UseDefaultFolder && Directory.Exists(this.automaticDownloader.Settings.DefaultFolder))
            {
                DownloadSelectedFiles(this.dgvPendingDownloads, this.automaticDownloader.Settings.DefaultFolder, true);
            } 
            else if (this.copyFolderDialog.ShowDialog() == DialogResult.OK && Directory.Exists(this.copyFolderDialog.SelectedPath))
            {
                DownloadSelectedFiles(this.dgvPendingDownloads, this.copyFolderDialog.SelectedPath, true);
            }
        }

        private string TicksToSeconds(long ticks)
        {
            double res = (double)ticks / 10000000;
            return res.ToString("0.00", MyCi.NumberFormat);
        }

        private void dgvSearchResults_SelectionChanged(object sender, EventArgs e)
        {
            DataGridView dgv = sender as DataGridView;
            if (dgv.SelectedRows.Count == 1)
            {
                DataGridViewRow row = dgv.SelectedRows[0];
                long fileID = (long)row.Cells["FileID"].Value;
                lblFileNameVal1.Text = (string)row.Cells["Name"].Value;
                toolTip1.SetToolTip(lblFileNameVal1, lblFileNameVal1.Text);
                lblFileLocationVal1.Text = (string)row.Cells["Location"].Value;
                lblFilePathVal1.Text = (string)row.Cells["Fullpath"].Value;
                toolTip1.SetToolTip(lblFilePathVal1, lblFilePathVal1.Text);
                lblFileSizeVal1.Text = (string)row.Cells["TotalLengthMB"].Value;
                LoadFileStats(fileID, 1);
                SetFileInfoVisible(true, 1);
            }
            else
            {
                SetFileInfoVisible(false, 1);
            }
        }

        private void dgvPendingDownloads_SelectionChanged(object sender, EventArgs e)
        {
            DataGridView dgv = sender as DataGridView;
            if (dgv.SelectedRows.Count == 1)
            {
                DataGridViewRow row = dgv.SelectedRows[0];
                long fileID = (long)row.Cells["FileID"].Value;

                lblFileNameVal2.Text = (string)row.Cells["Name"].Value;
                toolTip1.SetToolTip(lblFileNameVal2, lblFileNameVal2.Text);
                lblFileLocationVal2.Text = (string)row.Cells["Location"].Value;
                lblFilePathVal2.Text = (string)row.Cells["Fullpath"].Value;
                toolTip1.SetToolTip(lblFilePathVal2, lblFilePathVal2.Text);
                lblFileSizeVal2.Text = (string)row.Cells["TotalLengthMB"].Value;
                LoadFileStats(fileID, 2);
                SetFileInfoVisible(true, 2);
            }
            else
            {
                SetFileInfoVisible(false, 2);
            }
        }

        private void SetFileInfoVisible(bool state, int num)
        {
            if (num == 1)
            {

                lblFileName1.Visible = state;
                lblFileNameVal1.Visible = state;
                lblFileLocation1.Visible = state;
                lblFileLocationVal1.Visible = state;
                lblfilePath1.Visible = state;
                lblFilePathVal1.Visible = state;
                lblFileSize1.Visible = state;
                lblFileSizeVal1.Visible = state;
                lblFileTotalDownloads1.Visible = state;
                lblFileTotalDownloadsVal1.Visible = state;
                lblFileTotalVoted1.Visible = state;
                lblFileTotalVotedVal1.Visible = state;
                lblFileRating1.Visible = state;
                lblFileRatingVal1.Visible = state;
                lblFileMark1.Visible = state;
                numericMarkVal1.Visible = state;
                lblF21.Visible = !state;
                lblF51.Visible = !state;
                btnUpdateStats1.Visible = state;
            }
            else if (num == 2)
            {
                lblFileName2.Visible = state;
                lblFileNameVal2.Visible = state;
                lblFileLocation2.Visible = state;
                lblFileLocationVal2.Visible = state;
                lblFilePath2.Visible = state;
                lblFilePathVal2.Visible = state;
                lblFileSize2.Visible = state;
                lblFileSizeVal2.Visible = state;
                lblFileTotalDownloads2.Visible = state;
                lblFileTotalDownloadsVal2.Visible = state;
                lblFileTotalVoted2.Visible = state;
                lblFileTotalVotedVal2.Visible = state;
                lblFileRating2.Visible = state;
                lblFileRatingVal2.Visible = state;
                lblFileMark2.Visible = state;
                numericMarkVal2.Visible = state;
                lblF22.Visible = !state;
                lblF52.Visible = !state;
                btnUpdateStats2.Visible = state;
            }
        }

        private void dgvSearchResults_KeyDown(object sender, KeyEventArgs e)
        {
            DataGridView dgv = sender as DataGridView;
            if (e.KeyCode == Keys.F2 && dgv.SelectedRows.Count != 0)
            {
                DataGridViewRow row =  dgv.SelectedRows[0];
                long fileID = (long)row.Cells["FileID"].Value;
                lblFileNameVal1.Text = (string)row.Cells["Name"].Value;
                toolTip1.SetToolTip(lblFileNameVal1, lblFileNameVal1.Text);
                lblFileLocationVal1.Text = (string)row.Cells["Location"].Value;
                lblFilePathVal1.Text = (string)row.Cells["Fullpath"].Value;
                toolTip1.SetToolTip(lblFilePathVal1, lblFilePathVal1.Text);
                lblFileSizeVal1.Text = (string)row.Cells["TotalLengthMB"].Value;
                LoadFileStats(fileID, 1);
                SetFileInfoVisible(true, 1);
            }
            else if (e.KeyCode == Keys.F5 && dgv.SelectedRows.Count != 0)
            {
                if (this.automaticDownloader.Settings.UseDefaultFolder && Directory.Exists(this.automaticDownloader.Settings.DefaultFolder))
                {
                    DownloadSelectedFiles(dgv, this.automaticDownloader.Settings.DefaultFolder);
                }
                else if (this.copyFolderDialog.ShowDialog() == DialogResult.OK && Directory.Exists(this.copyFolderDialog.SelectedPath))
                {
                    DownloadSelectedFiles(dgv, this.copyFolderDialog.SelectedPath);
                }
            }
        }

        private void dgvPendingDownloads_KeyDown(object sender, KeyEventArgs e)
        {
            DataGridView dgv = sender as DataGridView;
            if (e.KeyCode == Keys.F2 && dgv.SelectedRows.Count != 0)
            {
                DataGridViewRow row = dgv.SelectedRows[0];
                long fileID = (long)row.Cells["FileID"].Value;
                lblFileNameVal2.Text = (string)row.Cells["Name"].Value;
                toolTip1.SetToolTip(lblFileNameVal2, lblFileNameVal2.Text);
                lblFileLocationVal2.Text = (string)row.Cells["Location"].Value;
                toolTip1.SetToolTip(lblFilePathVal2, lblFilePathVal2.Text);
                lblFilePathVal2.Text = (string)row.Cells["Fullpath"].Value;
                lblFileSizeVal2.Text = (string)row.Cells["TotalLengthMB"].Value;
                LoadFileStats(fileID, 2);
                SetFileInfoVisible(true, 2);
            }
            else if (e.KeyCode == Keys.F5 && dgv.SelectedRows.Count != 0)
            {
                if (this.automaticDownloader.Settings.UseDefaultFolder && Directory.Exists(this.automaticDownloader.Settings.DefaultFolder))
                {
                    DownloadSelectedFiles(dgv, this.automaticDownloader.Settings.DefaultFolder, true);
                }
                else if (this.copyFolderDialog.ShowDialog() == DialogResult.OK && Directory.Exists(this.copyFolderDialog.SelectedPath))
                {
                    DownloadSelectedFiles(dgv, this.copyFolderDialog.SelectedPath, true);
                }
            }
            else if (e.KeyCode == Keys.Delete && dgv.SelectedRows.Count != 0)
            {
                RemovePendingDownloads(dgv);
            }
        }

        private void RemovePendingDownloads(DataGridView dgv)
        {
            List<long> fileIDs = new List<long>();
            for (int i = 0; i < dgv.SelectedRows.Count; i++)
            {
                DataGridViewRow row = dgv.SelectedRows[i];
                fileIDs.Add((long)row.Cells["FileID"].Value);
            }
            fmService.RemovePendingDovnloadList((long)loginForm.User.Personid, fileIDs.ToArray(), 0);
            LoadPendingDownloads();
        }

        private void DownloadSelectedFiles(DataGridView dgv, string destPath)
        {
            DownloadSelectedFiles(dgv, destPath, false);
        }

        private void DownloadSelectedFiles(DataGridView dgv, string destPath, bool deleteFromPendingTable)
        {
            for (int i = 0; i < dgv.SelectedRows.Count; i++)
            {
                DataGridViewRow row = dgv.SelectedRows[i];
                CopyEntity entity = new CopyEntity();
                entity.FileID = (long)row.Cells["FileID"].Value;
                entity.FileLength = (long)row.Cells["Length"].Value;
                entity.SourcePath = (string)row.Cells["Fullpath"].Value;
                entity.SourceFileName = (string)row.Cells["Name"].Value;
                entity.CopyDestination = destPath;
                copyForm.AddFileToQueue(entity);
                if (deleteFromPendingTable)
                {
                    fmService.RemovePendingDovnload((long)loginForm.User.Personid, entity.FileID, 1);
                }
            }
            this.copyForm.Show();
            if (deleteFromPendingTable)
            {
                Musicman.Client.FileManagerService.SearchResult[] res = fmService.GetPendingDownloads((long)loginForm.User.Personid);
                ((BindingSource)this.dgvPendingDownloads.DataSource).DataSource = res;
            }
        }

        private void LoadFileStats(long fileID, int num)
        {
            Musicman.Client.FileManagerService.SearchFileStat fileStat = fmService.GetFileStats(fileID);
            if (num == 1)
            {
                lblFileTotalDownloadsVal1.Text = (fileStat.TotalDownloads == null) ? "" : fileStat.TotalDownloads.ToString();
                lblFileTotalVotedVal1.Text = (fileStat.TotalVoted == null) ? "" : fileStat.TotalVoted.ToString();
                lblFileRatingVal1.Text = (fileStat.Rating == null) ? "" : fileStat.Rating.ToString();
            }
            else if (num == 2)
            {
                lblFileTotalDownloadsVal2.Text = (fileStat.TotalDownloads == null) ? "" : fileStat.TotalDownloads.ToString();
                lblFileTotalVotedVal2.Text = (fileStat.TotalVoted == null) ? "" : fileStat.TotalVoted.ToString();
                lblFileRatingVal2.Text = (fileStat.Rating == null) ? "" : fileStat.Rating.ToString();
            }
        }

        private void btnUpdateStats1_Click(object sender, EventArgs e)
        {
            int mark = (int)this.numericMarkVal1.Value;
            if (mark != 0 && dgvSearchResults.SelectedRows.Count != 0)
            {
                long fileID = (long)dgvSearchResults.SelectedRows[0].Cells["FileID"].Value;
                fmService.UpdateFileStats(fileID, mark);
                LoadFileStats(fileID, 1);
            }
        }

        private void btnUpdateStats2_Click(object sender, EventArgs e)
        {
            int mark = (int)this.numericMarkVal2.Value;
            if (mark != 0 && dgvPendingDownloads.SelectedRows.Count != 0)
            {
                long fileID = (long)dgvPendingDownloads.SelectedRows[0].Cells["FileID"].Value;
                fmService.UpdateFileStats(fileID, mark);
                LoadFileStats(fileID, 2);
            }
        }

        private void btnRemove1_Click(object sender, EventArgs e)
        {
            if (dgvPendingDownloads.SelectedRows.Count != 0)
            {
                RemovePendingDownloads(dgvPendingDownloads);
            }
        }

        private void btnSaveSettings_Click(object sender, EventArgs e)
        {
            string settingsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal).ToString() + "\\settings.srl";
            FileStream fs = null;
            try
            {
                fs = File.Open(settingsPath, FileMode.Create, FileAccess.Write);
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(fs, this.automaticDownloader.Settings);
                fs.Flush();
                fs.Close();
            }
            catch (Exception ex)
            {
                fmService.LogClientException((long)loginForm.User.Personid,
                    "Error serializing user",
                    ex.Message,
                    (ex.InnerException == null) ? "" : ex.InnerException.Message);
                if (fs != null) fs.Close();
                File.Delete(settingsPath);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            bool changePassword = changePasswordCb.Checked;
            bool resume = true;
            if (firstNameTxt.Text == "")
            {
                lblEdtitUserMessage.Text = "First name field is mandatory";
                resume = false;
            }
            else if (lastNameTxt.Text == "")
            {
                lblEdtitUserMessage.Text = "Last name field is mandatory";
                resume = false;
            }
            if (changePassword)
            {
                if (passwordTxt.Text != loginForm.User.Password)
                {
                    lblEdtitUserMessage.Text = "Wrong old password";
                    resume = false;
                }
                else
                {
                    if (newPasswordTxt.Text != retypePasswordTxt.Text || newPasswordTxt.Text.Trim() == "")
                    {
                        lblEdtitUserMessage.Text = "Retype password correctly";
                        resume = false;
                    }
                    else
                    {
                        loginForm.User.Password = newPasswordTxt.Text;
                    }
                }
            }
            if (resume)
            {
                string originalPass = loginForm.User.Password;
                loginForm.User.Password = PassEncrypting(originalPass);
                this.aHeader.user = loginForm.User;
                this.aService.AuthHeaderValue = this.aHeader;
                this.aService.UpdateUserProfile();
                loginForm.User.Password = originalPass;
                this.changePasswordCb.Checked = false;
            }
            else
            {
                lblEdtitUserMessage.Visible = true;
            }
        }

        private void changePasswordCb_CheckedChanged(object sender, EventArgs e)
        {
            bool state = ((CheckBox)sender).Checked;
            passwordTxt.Enabled = state;
            newPasswordTxt.Enabled = state;
            retypePasswordTxt.Enabled = state;
        }

        static public string PassEncrypting(string originalPass)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            Byte[] originalBytes;
            Byte[] encodedBytes;
            originalBytes = ASCIIEncoding.Default.GetBytes(originalPass);
            encodedBytes = md5.ComputeHash(originalBytes);
            return BitConverter.ToString(encodedBytes);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.automaticDownloader.RequestState();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.automaticDownloader.StartDownloader();
        }

        private void dgvFeedbacks_SelectionChanged(object sender, EventArgs e)
        {
            DataGridView dgv = sender as DataGridView;
            if (dgv.SelectedRows.Count == 1 && dgv.SelectedRows[0].Index != -1)
            {
                int index = dgv.SelectedRows[0].Index;

                Musicman.Client.FeedbackService.Userfeedback uf =
                    ((Musicman.Client.FeedbackService.Userfeedback[])(((BindingSource)dgv.DataSource).DataSource))[index];
                BindUserFeedback(uf);
            }
            else
            {
                BindUserFeedback(new Musicman.Client.FeedbackService.Userfeedback());
            }
        }

        private void BindUserFeedback(Musicman.Client.FeedbackService.Userfeedback uf)
        {
            this.lblFrom.DataBindings.Clear();
            this.lblFrom.DataBindings.Add(new Binding("Text", uf, "From"));
            this.txtFeedbackSubject.DataBindings.Clear();
            this.txtFeedbackSubject.DataBindings.Add(new Binding("Text", uf, "Subject"));
            this.lblDate.DataBindings.Clear();
            this.lblDate.DataBindings.Add(new Binding("Text", uf, "Date"));
            this.txtFeedback.DataBindings.Clear();
            this.txtFeedback.DataBindings.Add(new Binding("Text", uf, "Feedback"));

            this.txtFeedbackSubject.Enabled = uf.Personid == this.loginForm.User.Personid;
            this.txtFeedback.Enabled = uf.Personid == this.loginForm.User.Personid;
            this.btnDeleteFeedback.Enabled = uf.Personid == this.loginForm.User.Personid;
            this.btnSaveFeedback.Enabled = uf.Personid == this.loginForm.User.Personid;
        }

        private void btnNewFeedback_Click(object sender, EventArgs e)
        {
            Musicman.Client.FeedbackService.Userfeedback uf = new Musicman.Client.FeedbackService.Userfeedback();
            uf.From = String.Format("{0} {1}", loginForm.User.Firstname, loginForm.User.Lastname);
            uf.Personid = loginForm.User.Personid;
            uf.Date = DateTime.Now;
            BindUserFeedback(uf);
        }

        private void btnSaveFeedback_Click(object sender, EventArgs e)
        {
            Musicman.Client.FeedbackService.Userfeedback uf = (Musicman.Client.FeedbackService.Userfeedback)this.txtFeedback.DataBindings[0].DataSource;
            fdbService.SaveUserFeedback(uf);
            if (uf.Id == null)
            {
                LoadUserFeedbackDates();
            }
            else
            {
                dgvFeedBackDates_SelectionChanged(dgvFeedBackDates, new EventArgs());
            }
        }

        private void btnDeleteFeedback_Click(object sender, EventArgs e)
        {
            Musicman.Client.FeedbackService.Userfeedback uf = (Musicman.Client.FeedbackService.Userfeedback)this.txtFeedback.DataBindings[0].DataSource;
            if (uf.Id != null)
            {
                fdbService.DeleteUserFeedback((long)uf.Id);
                dgvFeedBackDates_SelectionChanged(dgvFeedBackDates, new EventArgs());
            }

        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            this.btnSearch_Click(btnSearch, e);
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            this.btnTopDownloads_Click(btnTopDownloads, e);
        }

        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            this.btnTopRated_Click(btnTopRated, e);
        }

        private void toolStripMenuItem4_Click(object sender, EventArgs e)
        {
            this.btnRandom_Click(btnRandom, e);
        }

        private void toolStripMenuItem5_Click(object sender, EventArgs e)
        {
            this.btnLatest_Click(btnLatest, e);
        }

        private void toolStripMenuItem6_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void cbUseDefaultFolder_CheckedChanged(object sender, EventArgs e)
        {
             this.txtDefaultFolder.Enabled = ((CheckBox)sender).Checked;
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            if (this.copyFolderDialog.ShowDialog() == DialogResult.OK && Directory.Exists(this.copyFolderDialog.SelectedPath))
            {
                this.automaticDnloaderSettings.DefaultFolder = this.copyFolderDialog.SelectedPath;
                this.txtDefaultFolder.DataBindings[0].ReadValue();
                this.toolTip1.SetToolTip(this.txtDefaultFolder, this.txtDefaultFolder.Text);
            }
        }

        private void menuOpenFolder_Click(object sender, EventArgs e)
        {
            if (this.dgvSearchResults.SelectedRows.Count == 1)
            {
                DataGridViewRow row = this.dgvSearchResults.SelectedRows[0];
                string path = (string)row.Cells["Fullpath"].Value;
                int index = path.LastIndexOf('\\');
                path = path.Substring(0, index);
                if (Directory.Exists(path))
                {
                    Process p = new Process();
                    p.StartInfo.FileName = path;
                    p.Start();
                }
                else
                {
                    MessageBox.Show("Network path not available", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.dgvSearchResults.SelectedRows.Count == 1)
            {
                DataGridViewRow row = this.dgvSearchResults.SelectedRows[0];
                string path = (string)row.Cells["Fullpath"].Value;
                if (File.Exists(path))
                {
                    try
                    {
                        Process p = new Process();
                        p.StartInfo.FileName = path;
                        p.Start();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Unable to open file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        fmService.LogClientException((long)loginForm.User.Personid,
                            "Unable to open file",
                            ex.Message,
                            (ex.InnerException == null) ? "" : ex.InnerException.Message);
                    }
                }
                else
                {
                    MessageBox.Show("The file do not exist on local network", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }


    }
}